// 同一改成用户和店铺的登录注册
const { shop, user } = require('../models/index')
const uuidv5 = require('uuid/v5')
const bcrypt = require('bcrypt')
const authController = require('../controller/authController')
const tokenController = require('../controller/tokenController')
const tokenGenerator = require('../util/tokenGenerator')
const shopController = require('../controller/shopController')
const userController = require('../controller/userController')
const errorHelper = require('../util/errorHelper')

class AccountController {
  constructor() {
    // empty
  }

  async createAccount({ type, email, password, avatar }) {
    // type指示注册用户或者店铺
    const checkAuth = await authController.isAuthExist({
      type,
      where: {
        identityType: 'email',
        identifier: email
      }
    })
    if (checkAuth.length) {
      throw errorHelper(400, 'account duplicate')
    }
    // 根据邮箱生成用户或店铺id
    const Id = `${type}-${uuidv5(email, uuidv5.URL)}`
    // 创建用户或店铺
    const newAccount =
      type === 'shop' ? await shop.create({ shopId: Id, avatar }) : await user.create({ userId: Id, avatar })
    if (!newAccount) {
      throw errorHelper(400, 'account duplicate')
    }
    // 通过用户提交的密码生成身份验证字符串
    const salt = bcrypt.genSaltSync(this.saltSounds)
    const credential = bcrypt.hashSync(password, salt)
    const newAuth = await authController.createAuth({
      type,
      uuId: Id,
      identityType: 'email',
      identifier: email,
      credential
    })
    if (!newAuth) {
      throw errorHelper(400, 'account duplicate')
    }
    return Id
  }

  async login({ type, identityType, identifier, password, device, ip }) {
    // 先对比password和auth表中对应的密码，然后存储token表记录
    const checkAuth = await authController.isAuthExist({
      type,
      where: {
        identityType,
        identifier
      }
    })
    const targetAuth = checkAuth[0]
    if (!bcrypt.compareSync(password, targetAuth.credential)) {
      throw errorHelper(400, 'account or password error')
    }
    // 根据密码生成token
    const loginToken = tokenGenerator.generate(identifier, 10)
    const loginTime = new Date()
    const outdateTime = new Date(loginTime.getTime() + 12 * 3600 * 1000) // token有效期：12小时
    const uuId = type === 'shop' ? targetAuth.shopId : targetAuth.userId
    const token = await tokenController.createToken({
      type,
      uuId,
      identityType,
      loginToken,
      loginTime,
      outdateTime,
      device,
      ip
    })
    const accountDetail =
      type === 'shop'
        ? await shopController.getDetailByShopId(targetAuth.shopId)
        : await userController.getDetailByUserId(targetAuth.userId)
    return { accountDetail, token: token.token }
  }
}
module.exports = new AccountController()
